home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / gedit-2 / plugins / pythonconsole / console.py < prev    next >
Encoding:
Python Source  |  2009-04-14  |  10.2 KB  |  327 lines

  1. # -*- coding: utf-8 -*-
  2.  
  3. # pythonconsole.py -- Console widget
  4. #
  5. # Copyright (C) 2006 - Steve Fr√©cinaux
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2, or (at your option)
  10. # any later version.
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19.  
  20. # Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
  21. #     Copyright (C), 1998 James Henstridge <james@daa.com.au>
  22. #     Copyright (C), 2005 Adam Hooper <adamh@densi.com>
  23. # Bits from gedit Python Console Plugin
  24. #     Copyrignt (C), 2005 Rapha√´l Slinckx
  25.  
  26. import string
  27. import sys
  28. import re
  29. import traceback
  30. import gobject
  31. import gtk
  32. import pango
  33.  
  34. from config import PythonConsoleConfig
  35.  
  36. __all__ = ('PythonConsole', 'OutFile')
  37.  
  38. class PythonConsole(gtk.ScrolledWindow):
  39.     def __init__(self, namespace = {}):
  40.         gtk.ScrolledWindow.__init__(self)
  41.  
  42.         self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
  43.         self.set_shadow_type(gtk.SHADOW_IN)
  44.         self.view = gtk.TextView()
  45.         self.view.modify_font(pango.FontDescription('Monospace'))
  46.         self.view.set_editable(True)
  47.         self.view.set_wrap_mode(gtk.WRAP_WORD_CHAR)
  48.         self.add(self.view)
  49.         self.view.show()
  50.  
  51.         buffer = self.view.get_buffer()
  52.         self.normal = buffer.create_tag("normal")
  53.         self.error  = buffer.create_tag("error")
  54.         self.command = buffer.create_tag("command")
  55.  
  56.         PythonConsoleConfig.add_handler(self.apply_preferences)
  57.         self.apply_preferences()
  58.  
  59.         self.__spaces_pattern = re.compile(r'^\s+')
  60.         self.namespace = namespace
  61.  
  62.         self.block_command = False
  63.  
  64.         # Init first line
  65.         buffer.create_mark("input-line", buffer.get_end_iter(), True)
  66.         buffer.insert(buffer.get_end_iter(), ">>> ")
  67.         buffer.create_mark("input", buffer.get_end_iter(), True)
  68.  
  69.         # Init history
  70.         self.history = ['']
  71.         self.history_pos = 0
  72.         self.current_command = ''
  73.         self.namespace['__history__'] = self.history
  74.  
  75.         # Set up hooks for standard output.
  76.         self.stdout = OutFile(self, sys.stdout.fileno(), self.normal)
  77.         self.stderr = OutFile(self, sys.stderr.fileno(), self.error)
  78.         
  79.         # Signals
  80.         self.view.connect("key-press-event", self.__key_press_event_cb)
  81.         buffer.connect("mark-set", self.__mark_set_cb)
  82.         
  83.     def apply_preferences(self, *args):
  84.         config = PythonConsoleConfig()
  85.         self.error.set_property("foreground", config.color_error)
  86.         self.command.set_property("foreground", config.color_command)
  87.         
  88.     def stop(self):
  89.         self.namespace = None
  90.  
  91.     def __key_press_event_cb(self, view, event):
  92.         modifier_mask = gtk.accelerator_get_default_mod_mask()
  93.         event_state = event.state & modifier_mask
  94.  
  95.         if event.keyval == gtk.keysyms.d and event_state == gtk.gdk.CONTROL_MASK:
  96.             self.destroy()
  97.  
  98.         elif event.keyval == gtk.keysyms.Return and event_state == gtk.gdk.CONTROL_MASK:
  99.             # Get the command
  100.             buffer = view.get_buffer()
  101.             inp_mark = buffer.get_mark("input")
  102.             inp = buffer.get_iter_at_mark(inp_mark)
  103.             cur = buffer.get_end_iter()
  104.             line = buffer.get_text(inp, cur)
  105.             self.current_command = self.current_command + line + "\n"
  106.             self.history_add(line)
  107.  
  108.             # Prepare the new line
  109.             cur = buffer.get_end_iter()
  110.             buffer.insert(cur, "\n... ")
  111.             cur = buffer.get_end_iter()
  112.             buffer.move_mark(inp_mark, cur)
  113.             
  114.             # Keep indentation of precendent line
  115.             spaces = re.match(self.__spaces_pattern, line)
  116.             if spaces is not None:
  117.                 buffer.insert(cur, line[spaces.start() : spaces.end()])
  118.                 cur = buffer.get_end_iter()
  119.                 
  120.             buffer.place_cursor(cur)
  121.             gobject.idle_add(self.scroll_to_end)
  122.             return True
  123.         
  124.         elif event.keyval == gtk.keysyms.Return:
  125.             # Get the marks
  126.             buffer = view.get_buffer()
  127.             lin_mark = buffer.get_mark("input-line")
  128.             inp_mark = buffer.get_mark("input")
  129.  
  130.             # Get the command line
  131.             inp = buffer.get_iter_at_mark(inp_mark)
  132.             cur = buffer.get_end_iter()
  133.             line = buffer.get_text(inp, cur)
  134.             self.current_command = self.current_command + line + "\n"
  135.             self.history_add(line)
  136.  
  137.             # Make the line blue
  138.             lin = buffer.get_iter_at_mark(lin_mark)
  139.             buffer.apply_tag(self.command, lin, cur)
  140.             buffer.insert(cur, "\n")
  141.             
  142.             cur_strip = self.current_command.rstrip()
  143.  
  144.             if cur_strip.endswith(":") \
  145.             or (self.current_command[-2:] != "\n\n" and self.block_command):
  146.                 # Unfinished block command
  147.                 self.block_command = True
  148.                 com_mark = "... "
  149.             elif cur_strip.endswith("\\"):
  150.                 com_mark = "... "
  151.             else:
  152.                 # Eval the command
  153.                 self.__run(self.current_command)
  154.                 self.current_command = ''
  155.                 self.block_command = False
  156.                 com_mark = ">>> "
  157.  
  158.             # Prepare the new line
  159.             cur = buffer.get_end_iter()
  160.             buffer.move_mark(lin_mark, cur)
  161.             buffer.insert(cur, com_mark)
  162.             cur = buffer.get_end_iter()
  163.             buffer.move_mark(inp_mark, cur)
  164.             buffer.place_cursor(cur)
  165.             gobject.idle_add(self.scroll_to_end)
  166.             return True
  167.  
  168.         elif event.keyval == gtk.keysyms.KP_Down or event.keyval == gtk.keysyms.Down:
  169.             # Next entry from history
  170.             view.emit_stop_by_name("key_press_event")
  171.             self.history_down()
  172.             gobject.idle_add(self.scroll_to_end)
  173.             return True
  174.  
  175.         elif event.keyval == gtk.keysyms.KP_Up or event.keyval == gtk.keysyms.Up:
  176.             # Previous entry from history
  177.             view.emit_stop_by_name("key_press_event")
  178.             self.history_up()
  179.             gobject.idle_add(self.scroll_to_end)
  180.             return True
  181.  
  182.         elif event.keyval == gtk.keysyms.KP_Left or event.keyval == gtk.keysyms.Left or \
  183.              event.keyval == gtk.keysyms.BackSpace:
  184.             buffer = view.get_buffer()
  185.             inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  186.             cur = buffer.get_iter_at_mark(buffer.get_insert())
  187.             if inp.compare(cur) == 0:
  188.                 if not event_state:
  189.                     buffer.place_cursor(inp)
  190.                 return True
  191.             return False
  192.  
  193.         elif (event.keyval == gtk.keysyms.KP_Home or event.keyval == gtk.keysyms.Home) and \
  194.              event_state == event_state & (gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK):
  195.             # Go to the begin of the command instead of the begin of the line
  196.             buffer = view.get_buffer()
  197.             inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  198.             if event_state & gtk.gdk.SHIFT_MASK:
  199.                 buffer.move_mark_by_name("insert", inp)
  200.             else:
  201.                 buffer.place_cursor(inp)
  202.             return True
  203.         
  204.     def __mark_set_cb(self, buffer, iter, name):
  205.         input = buffer.get_iter_at_mark(buffer.get_mark("input"))
  206.         pos   = buffer.get_iter_at_mark(buffer.get_insert())
  207.         self.view.set_editable(pos.compare(input) != -1)
  208.  
  209.     def get_command_line(self):
  210.         buffer = self.view.get_buffer()
  211.         inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  212.         cur = buffer.get_end_iter()
  213.         return buffer.get_text(inp, cur)
  214.     
  215.     def set_command_line(self, command):
  216.         buffer = self.view.get_buffer()
  217.         mark = buffer.get_mark("input")
  218.         inp = buffer.get_iter_at_mark(mark)
  219.         cur = buffer.get_end_iter()
  220.         buffer.delete(inp, cur)
  221.         buffer.insert(inp, command)
  222.         self.view.grab_focus()
  223.     
  224.     def history_add(self, line):
  225.         if line.strip() != '':
  226.             self.history_pos = len(self.history)
  227.             self.history[self.history_pos - 1] = line
  228.             self.history.append('')
  229.     
  230.     def history_up(self):
  231.         if self.history_pos > 0:
  232.             self.history[self.history_pos] = self.get_command_line()
  233.             self.history_pos = self.history_pos - 1
  234.             self.set_command_line(self.history[self.history_pos])
  235.             
  236.     def history_down(self):
  237.         if self.history_pos < len(self.history) - 1:
  238.             self.history[self.history_pos] = self.get_command_line()
  239.             self.history_pos = self.history_pos + 1
  240.             self.set_command_line(self.history[self.history_pos])
  241.     
  242.     def scroll_to_end(self):
  243.         iter = self.view.get_buffer().get_end_iter()
  244.         self.view.scroll_to_iter(iter, 0.0)
  245.         return False
  246.  
  247.     def write(self, text, tag = None):
  248.         buffer = self.view.get_buffer()
  249.         if tag is None:
  250.             buffer.insert(buffer.get_end_iter(), text)
  251.         else:
  252.             buffer.insert_with_tags(buffer.get_end_iter(), text, tag)
  253.         gobject.idle_add(self.scroll_to_end)
  254.      
  255.      def eval(self, command, display_command = False):
  256.         buffer = self.view.get_buffer()
  257.         lin = buffer.get_mark("input-line")
  258.         buffer.delete(buffer.get_iter_at_mark(lin),
  259.                       buffer.get_end_iter())
  260.  
  261.         if isinstance(command, list) or isinstance(command, tuple):
  262.              for c in command:
  263.                  if display_command:
  264.                      self.write(">>> " + c + "\n", self.command)
  265.                  self.__run(c)
  266.         else:
  267.              if display_command:
  268.                  self.write(">>> " + c + "\n", self.command)
  269.             self.__run(command) 
  270.  
  271.         cur = buffer.get_end_iter()
  272.         buffer.move_mark_by_name("input-line", cur)
  273.         buffer.insert(cur, ">>> ")
  274.         cur = buffer.get_end_iter()
  275.         buffer.move_mark_by_name("input", cur)
  276.         self.view.scroll_to_iter(buffer.get_end_iter(), 0.0)
  277.     
  278.      def __run(self, command):
  279.         sys.stdout, self.stdout = self.stdout, sys.stdout
  280.         sys.stderr, self.stderr = self.stderr, sys.stderr
  281.  
  282.         # eval and exec are broken in how they deal with utf8-encoded
  283.         # strings so we have to explicitly decode the command before
  284.         # passing it along
  285.         command = command.decode('utf8')
  286.  
  287.         try:
  288.             try:
  289.                 r = eval(command, self.namespace, self.namespace)
  290.                 if r is not None:
  291.                     print `r`
  292.             except SyntaxError:
  293.                 exec command in self.namespace
  294.         except:
  295.             if hasattr(sys, 'last_type') and sys.last_type == SystemExit:
  296.                 self.destroy()
  297.             else:
  298.                 traceback.print_exc()
  299.  
  300.         sys.stdout, self.stdout = self.stdout, sys.stdout
  301.         sys.stderr, self.stderr = self.stderr, sys.stderr
  302.  
  303.     def destroy(self):
  304.         pass
  305.         #gtk.ScrolledWindow.destroy(self)
  306.         
  307. class OutFile:
  308.     """A fake output file object. It sends output to a TK test widget,
  309.     and if asked for a file number, returns one set on instance creation"""
  310.     def __init__(self, console, fn, tag):
  311.         self.fn = fn
  312.         self.console = console
  313.         self.tag = tag
  314.     def close(self):         pass
  315.     def flush(self):         pass
  316.     def fileno(self):        return self.fn
  317.     def isatty(self):        return 0
  318.     def read(self, a):       return ''
  319.     def readline(self):      return ''
  320.     def readlines(self):     return []
  321.     def write(self, s):      self.console.write(s, self.tag)
  322.     def writelines(self, l): self.console.write(l, self.tag)
  323.     def seek(self, a):       raise IOError, (29, 'Illegal seek')
  324.     def tell(self):          raise IOError, (29, 'Illegal seek')
  325.     truncate = tell
  326.